import { useQuery } from '@/hooks/useQuery'
import WindowLayout from '@/layout/WindowLayout'
import { gameStore } from '@/store/gameStore'
import { Game, LocalFile, PrevieMedia } from '@/type'
import { observer } from 'mobx-react-lite'
import { useEffect, useRef, useState } from 'react'
import { gameSorts } from './lib'
import './scss/GameInfo.scss'
import { base64ToFile, compressImage, sleep } from '@/utils/common'
import GameStartManager from '@/lib/GameStartManager'
import { showToast } from '@/utils/toast'
import BackSvg from '@/svg/BackSvg'
import { useNavigate } from 'react-router-dom'
import { open } from '@tauri-apps/plugin-dialog'
import {
  Button,
  Input,
  Popover,
  PopoverContent,
  PopoverTrigger,
  Tab,
  Tabs,
  Textarea,
} from '@heroui/react'
import { invoke } from '@tauri-apps/api/core'
import ImageSelect from '@/components/ImageSelect'
import FileSaveManager from '@/lib/FileSaveManager'
import RemoveSvg from '@/svg/RemoveSvg'
import AddSvg from '@/svg/AddSvg'
import RadioGroup from '@/components/RadioGroup'
import { diff2 } from '@/utils/compare'

const switchLocalFile = (old: LocalFile, newFile: LocalFile) => {
  if (old == null) return newFile
  if (old.path === newFile.path) return old
  sleep(400).then(() => {
    FileSaveManager.removeFile(old)
  })
  return newFile
}
const GameInfo = () => {
  const navigate = useNavigate()
  const query = useQuery()
  const gameId = query.id
  const game = gameStore.value.games.find((item) => item.id === gameId)
  const sort = query.sort
  const nextGame = useRef<Game>(null)
  const prevGame = useRef<Game>(null)
  useEffect(() => {
    const sortGame = gameSorts
      .find((item) => item.value === sort)
      .toSort(gameStore.value.games)
    const index = sortGame.findIndex((item) => item.id === game?.id)
    nextGame.current = sortGame[index + 1] || null
    prevGame.current = sortGame[index - 1] || null
  }, [game, sort])
  const [loading, setLoading] = useState(false)

  async function startGame() {
    if (loading) return
    setLoading(true)
    try {
      await GameStartManager.startGame(game)
      await sleep(1500)
      showToast('游戏启动成功')
    } finally {
      setLoading(false)
    }
  }
  function toGameInfo(game: Game | null) {
    if (!game) {
      showToast('已经到尽头了')
    }
    const { id } = game
    navigate(`/info?id=${id}&sort=${sort}`, {
      replace: true,
    })
  }
  function openGameDir(): void {
    const path = game.openFilePath.replace(/\\/g, '/')
    const paths = path.split('/')
    const dir = paths.slice(0, paths.length - 1).join('/')
    invoke('open_file', { path: dir })
  }
  const [form, setForm] = useState<Game>(null)
  useEffect(() => {
    if (!game) return
    setForm(JSON.parse(JSON.stringify(game)))
  }, [game])

  const previewMultiRef = useRef(null)

  function verify() {
    if (!form.name) {
      showToast('请输入游戏名称')
      return false
    }
    if (!form.cover) {
      showToast('请选择竖屏封面图')
      return false
    }
    if (!form.thumb) {
      showToast('请选择横屏封面图')
      return false
    }
    if (form.openMode == 'file' && !form.openFilePath) {
      showToast('请选择启动文件路径')
      return false
    } else if (form.openMode == 'cmd' && !form.openCmd) {
      showToast('请输入启动命令')
      return false
    }
    return true
  }
  const onSave = async () => {
    if (!verify()) return
    setLoading(true)
    const previeMedia: PrevieMedia[] = []
    try {
      for (let i = 0; i < form.previeMedia.length; i++) {
        const item = form.previeMedia[i]
        previeMedia.push({
          type: item.type,
          data: switchLocalFile(game.previeMedia[i]?.data, item.data),
        })
      }
      diff2(
        previeMedia,
        game.previeMedia,
        (a, b) => a.data.path === b.data.path
      ).forEach((i) =>
        sleep(200).then(() => FileSaveManager.removeFile(i.data))
      )
      const params: Game = {
        id: form.id,
        name: form.name,
        description: form.description,
        cover: switchLocalFile(game.cover, form.cover),
        thumb: switchLocalFile(game.thumb, form.thumb),
        openMode: form.openMode,
        openCmd: form.openCmd,
        openFilePath: form.openFilePath,
        previeMedia,
        createTime: game.createTime,
      }
      gameStore.setValue('games', [
        params,
        ...gameStore.value.games.filter((item) => item.id !== form.id),
      ])
    } catch (e) {
      console.error(e)
      showToast('添加失败')
    } finally {
      setLoading(false)
    }
    showToast('保存成功')
  }
  const removeGame = async () => {
    showToast('删除成功')
    navigate(-1)
    const gameId = game.id

    const gameList = gameStore.value.games.filter((item) => item.id != gameId)
    gameStore.setValue('games', gameList)
    sleep(200).then(() => {
      FileSaveManager.removeFile(game.cover)
      FileSaveManager.removeFile(game.thumb)
      game.previeMedia.forEach((item) => {
        FileSaveManager.removeFile(item.data)
      })
    })
  }

  return (
    <WindowLayout>
      <div className="GameInfo">
        <div className="thumb">
          <img src={game?.thumb?.url} alt="" draggable={false} />
          <div className="mask"></div>
          <div
            className="back"
            onClick={() => {
              navigate(-1)
            }}>
            <BackSvg />
          </div>
        </div>
        <div className="startGame">
          <div className="cover">
            <img src={game?.cover?.url} alt="" draggable={false} />
          </div>
          <div className="right-content">
            <div className="name">{game.name}</div>
            <div className="desc">介绍：{game.description || '无'}</div>
            <div className="btns">
              <button
                className={`button${loading ? ' loading-state' : ''}`}
                onClick={startGame}>
                <span>启动游戏</span>
                <div className="loading">
                  <div></div>
                  <div></div>
                </div>
              </button>
              <button
                className="button-sold"
                onClick={() => toGameInfo(prevGame.current)}>
                <span>上一款</span>
              </button>
              <button
                className="button-sold"
                onClick={() => toGameInfo(nextGame.current)}>
                <span>下一款</span>
              </button>
              {game.openMode == 'file' && (
                <button
                  className="button-sold"
                  style={{
                    width: 'fit-content',
                  }}
                  onClick={() => openGameDir()}>
                  <span>打开启动文件路径</span>
                </button>
              )}
            </div>
          </div>
        </div>

        <div className="tabs">
          <Tabs
            style={{
              width: 300,
            }}>
            <Tab key={'preview'} title="预览">
              <div className="preview-list">
                {game.previeMedia.map((item, index) => {
                  return (
                    <div className="preview-item" key={index}>
                      {item.type === 'image' ? (
                        <img src={item.data.url} alt="" draggable={false} />
                      ) : (
                        <video src={item.data.url} controls draggable={false} />
                      )}
                    </div>
                  )
                })}
              </div>
              {game.previeMedia.length == 0 && (
                <div className="empty">
                  <span>暂无预览</span>
                </div>
              )}
            </Tab>
            <Tab key={'setting'} title="设置">
              {form != null && (
                <div
                  className="AddGameModal"
                  style={{
                    display: 'flex',
                    flexDirection: 'column',
                    gap: 16,
                  }}>
                  <div className="form-item">
                    <div className="form-label">游戏名称</div>
                    <div className="form-input">
                      <Input
                        value={form.name}
                        onChange={(e) => {
                          setForm({ ...form, name: e.target.value })
                        }}
                        size="sm"
                        placeholder="请输入游戏名称"
                        style={{
                          width: 300,
                        }}
                      />
                    </div>
                  </div>
                  <div className="form-item">
                    <div className="form-label">竖屏封面图</div>
                    <div className="form-input">
                      <ImageSelect
                        value={form.cover.url}
                        onChange={async (e) => {
                          if (form.cover.path !== game.cover.path) {
                            sleep(200).then(() =>
                              FileSaveManager.removeFile(form.cover)
                            )
                          }
                          setForm({
                            ...form,
                            cover: await FileSaveManager.saveFileToUrl(
                              await compressImage(
                                base64ToFile(e, 'cover.png'),
                                460
                              ),
                              'cover'
                            ),
                          })
                        }}
                        clipAspect={1.3}
                      />
                    </div>
                  </div>
                  <div className="form-item">
                    <div className="form-label">横屏封面图</div>
                    <div className="form-input">
                      <ImageSelect
                        width={300}
                        value={form.thumb.url}
                        onChange={async (e) => {
                          if (form.thumb.path !== game.thumb.path) {
                            sleep(200).then(() =>
                              FileSaveManager.removeFile(form.thumb)
                            )
                          }
                          setForm({
                            ...form,
                            thumb: await FileSaveManager.saveFileToUrl(
                              base64ToFile(e, 'thumb.png'),
                              'thumb'
                            ),
                          })
                        }}
                        clipAspect={0.6}
                      />
                    </div>
                  </div>
                  <div className="form-item">
                    <div className="form-label">游戏详情</div>
                    <div className="form-input">
                      <Textarea
                        value={form.description}
                        onChange={(e) => {
                          setForm({ ...form, description: e.target.value })
                        }}
                        placeholder="请输入游戏详情"
                        size="sm"
                        style={{
                          width: 500,
                          height: 200,
                        }}
                      />
                    </div>
                  </div>
                  <div className="form-item">
                    <div className="form-label">游戏预览</div>
                    <div className="form-input">
                      <div className="preview-box">
                        <input
                          style={{
                            display: 'none',
                          }}
                          type="file"
                          accept="image/*,video/*"
                          multiple={true}
                          ref={previewMultiRef}
                          onChange={async (e) => {
                            const files = e.target.files
                            const list: PrevieMedia[] = []
                            for (let i = 0; i < files.length; i++) {
                              const file = files[i]
                              if (file.type.startsWith('image')) {
                                list.push({
                                  type: 'image',
                                  data: await FileSaveManager.saveFileToUrl(
                                    file,
                                    'preview-image'
                                  ),
                                })
                              } else if (file.type.startsWith('video')) {
                                list.push({
                                  type: 'video',
                                  data: await FileSaveManager.saveFileToUrl(
                                    file,
                                    'preview-image'
                                  ),
                                })
                              }
                            }
                            setForm({
                              ...form,
                              previeMedia: [
                                ...form.previeMedia,
                                ...list,
                              ] as any,
                            })
                          }}
                        />
                        {form.previeMedia.map((item, index) => {
                          return (
                            <div className="item" key={index}>
                              {item.type === 'image' && (
                                <img src={item.data.url} alt="" />
                              )}
                              {item.type === 'video' && (
                                <video controls src={item.data.url} />
                              )}
                              <div
                                className="remove-icon"
                                onClick={() => {
                                  const item = form.previeMedia[index]
                                  const some = game.previeMedia.some(
                                    (item2) =>
                                      item2.data.path === item.data.path
                                  )
                                  if (!some) {
                                    FileSaveManager.removeFile(item.data)
                                  }
                                  setForm({
                                    ...form,
                                    previeMedia: form.previeMedia.filter(
                                      (_, i) => i !== index
                                    ),
                                  })
                                }}>
                                <RemoveSvg />
                              </div>
                            </div>
                          )
                        })}

                        <div
                          className="add-item"
                          onClick={() => {
                            previewMultiRef.current.click()
                          }}>
                          <AddSvg />
                          <span>添加预览图片或视频</span>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div className="form-item">
                    <div className="form-label">启动模式</div>
                    <div className="form-input">
                      <RadioGroup
                        value={form.openMode}
                        onChange={(e) => {
                          setForm({ ...form, openMode: e })
                        }}
                        options={[
                          {
                            label: '文件打开',
                            value: 'file',
                          },
                          {
                            label: '命令行启动',
                            value: 'cmd',
                          },
                        ]}
                      />
                    </div>
                  </div>
                  {form.openMode === 'file' && (
                    <div className="form-item">
                      <div className="form-label">启动文件</div>
                      <div className="form-input">
                        <div className="path-select-box">
                          <span
                            className={form.openFilePath ? '' : 'placeholder'}>
                            {form.openFilePath
                              ? form.openFilePath
                              : '请选择启动文件'}
                          </span>
                          <Button
                            color={'primary'}
                            style={{
                              color: 'white',
                              width: 100,
                            }}
                            onPress={async () => {
                              const path = await open({
                                multiple: false,
                                directory: false,
                                filters: [
                                  {
                                    name: '可执行文件',
                                    extensions: ['exe', 'bat', 'cmd'],
                                  },
                                ],
                              })
                              if (path) {
                                setForm({ ...form, openFilePath: path })
                              }
                            }}
                            size="sm">
                            {form.openFilePath ? '重新选择' : '选择文件'}
                          </Button>
                        </div>
                      </div>
                    </div>
                  )}
                  {form.openMode === 'cmd' && (
                    <div className="form-item">
                      <div className="form-label">启动命令</div>
                      <div className="form-input">
                        <Input
                          value={form.openCmd}
                          onChange={(e) => {
                            setForm({ ...form, openCmd: e.target.value })
                          }}
                          placeholder="请输入游戏启动命令"
                          size="sm"
                          style={{
                            width: 500,
                          }}
                        />
                      </div>
                    </div>
                  )}
                </div>
              )}
              <div className="btns">
                <Popover placement="bottom" color="danger">
                  <PopoverTrigger>
                    <Button color="danger" size="sm">
                      删除游戏
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="drak">
                    <div>
                      <div
                        className="text-tiny"
                        style={{
                          marginBottom: 10,
                        }}>
                        确定要删除游戏 {game.name} 吗？
                      </div>
                      <Button
                        color="primary"
                        style={{
                          marginLeft: 'auto',
                          display: 'block',
                        }}
                        size="sm"
                        onPress={removeGame}>
                        确认删除
                      </Button>
                    </div>
                  </PopoverContent>
                </Popover>
                <Button
                  color="primary"
                  style={{
                    color: 'white',
                  }}
                  size="sm"
                  onPress={async () => {
                    onSave()
                  }}>
                  保存
                </Button>
              </div>
            </Tab>
          </Tabs>
        </div>
        <div
          style={{
            height: 300,
          }}></div>
      </div>
    </WindowLayout>
  )
}

export default observer(GameInfo)
